/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun<iot25@lingyun>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(24/04/25)
 *         Author:  LingYun <iot25@lingyun>
 *      ChangeLog:  1, Release initial version on "24/04/25 15:14:29"
 *                 
 ********************************************************************************/

#include "main.h"
#include "socket.h"
#include "sqlite.h"
#include "logger.h"


// 全局变量
client_ctx_t g_client_ctx = {0};


int main(int argc, char **argv)
{
    float temp = 0.0;
    time_t current_time;
    int rv = 0;
    int ch;
    char *server_ip = DEFAULT_SERVER_IP;
    int server_port = DEFAULT_SERVER_PORT;
    int report_interval = DEFAULT_REPORT_INTERVAL;
    struct option opts[] = {
        {"ipaddr", required_argument, NULL, 'i'},
        {"port", required_argument, NULL, 'p'},
        {"interval", required_argument, NULL, 't'},
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };

    // 解析命令行参数
    while ((ch = getopt_long(argc, argv, "i:p:t:h", opts, NULL)) != -1) {
        switch (ch) {
            case 'i':
                server_ip = optarg;
                break;
            case 'p':
                server_port = atoi(optarg);
                break;
            case 't':
                report_interval = atoi(optarg);
                break;
            case 'h':
                print_usage(argv[0]);
                return 0;
        }
    }

    if (!server_ip || server_port <= 0 || report_interval <= 0) {
        print_usage(argv[0]);
        return -1;
    }

    // 初始化客户端上下文
    if (init_client_context(&g_client_ctx, server_ip, server_port, report_interval) < 0) {
        fprintf(stderr, "Failed to initialize client context\n");
        return -1;
    }

    // 设置信号处理函数
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);

    // 初始化数据库
    if (init_database(&g_client_ctx) < 0) {
        fprintf(stderr, "Failed to initialize database\n");
        return -1;
    }

    // 尝试连接服务器
    connect_server(&g_client_ctx);

    // 如果连接成功，首先上报之前存储的数据
    if (g_client_ctx.sockfd > 0) {
        report_stored_data(&g_client_ctx);
    }

    printf("Client started. Reporting every %d seconds to %s:%d\n",
           g_client_ctx.report_interval, g_client_ctx.server_ip, g_client_ctx.server_port);

    // 主循环
    while (g_client_ctx.is_running) {
        // 获取当前温度
        if (get_temperature(&temp) == 0) {
            time(&current_time);
            printf("Current temperature: %.3f°C, Time: %s", temp, ctime(&current_time));

            // 尝试上报温度
            if (g_client_ctx.sockfd > 0) {
                if (report_temperature(&g_client_ctx, temp) < 0) {
                    // 上报失败，存储到数据库
                    printf("Failed to report temperature, storing in database\n");
                    store_temperature(&g_client_ctx, temp, current_time);

                    // 尝试重连
                    close(g_client_ctx.sockfd);
                    g_client_ctx.sockfd = -1;
                }
            } else {
                // 未连接服务器，存储到数据库
                printf("Not connected to server, storing in database\n");
                store_temperature(&g_client_ctx, temp, current_time);

                // 尝试重连
                connect_server(&g_client_ctx);

                // 如果重连成功，上报存储的数据
                if (g_client_ctx.sockfd > 0) {
                    report_stored_data(&g_client_ctx);
                }
            }
        } else {
            fprintf(stderr, "Failed to get temperature\n");
        }

        // 等待下一次上报
        sleep(g_client_ctx.report_interval);
    }

    // 清理资源
    if (g_client_ctx.sockfd > 0) {
        close(g_client_ctx.sockfd);
    }

    if (g_client_ctx.db) {
        sqlite3_close(g_client_ctx.db);
    }

    return 0;
}


void print_usage(char *progname)
{
    printf("%s usage:\n", progname);
    printf("--ipaddr or -i: specify server IP address (default: %s)\n", DEFAULT_SERVER_IP);
    printf("--port or -p: specify server port (default: %d)\n", DEFAULT_SERVER_PORT);
    printf("--interval or -t: specify report interval in seconds (default: %d)\n", DEFAULT_REPORT_INTERVAL);
    printf("--help or -h: print this information\n");
}

void signal_handler(int signo)
{
    printf("Received signal %d, exiting...\n", signo);
    g_client_ctx.is_running = 0;
}

